#ifdef HTTPD
#include <Arduino.h>
// #include <LwIP.h>
#include <STM32Ethernet.h>
#include <core_debug.h>
extern "C"
{
  void httpd_init(void);
}

#include <hwboard.h>
#include "lwip/apps/httpd.h"

void setReboot();

enum
{
#define XTAG(a) a,
#include "SSITag.h"
#undef XTAG
} SSITag;

static const char *ppcTAGs[] = //SSI的Tag
    {
#define XTAG(a) #a,
#include "SSITag.h"
#undef XTAG

};

int WEB_dis_Handler(char *dst, const char *src)
{
  int len = strlen(src);
  strncpy(dst, src, len);
  return len;
}
//SSI的Handler句柄
//根据不同的索引来插入对应的数据
//返回：插入数据的字符串长度
static u16_t SSIHandler(
#if LWIP_HTTPD_SSI_RAW
    const char *ssi_tag_name,
#else  /* LWIP_HTTPD_SSI_RAW */
    int iIndex,
#endif /* LWIP_HTTPD_SSI_RAW */
    char *pcInsert, int iInsertLen
#if LWIP_HTTPD_SSI_MULTIPART
    ,
    u16_t current_tag_part, u16_t *next_tag_part
#endif /* LWIP_HTTPD_SSI_MULTIPART */
#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
    ,
    void *connection_state
#endif /* LWIP_HTTPD_FILE_STATE */
)
{
  char buf[256];
  // FlashFile md;
  char *p;
  unsigned long tick = 0;
  unsigned long size = 0;
  char *buffer = 0;
  switch (iIndex)
  {
  case PLCMD5:
    // md.open_rdonly("lastbuildPLC.md5");
    // md.read(buf, 32);
    // md.close();
    return WEB_dis_Handler(pcInsert, buf);
  case XX:
    // for (int i = 0; i < XX_MAX; i++)
    // {
    //   p = &board.xx1;
    //   p += i;
    //   size += snprintf(buf + size, 256 - size, "<td>%d</td>", *p);
    // }
    buf[size] = 0;
    strncpy(pcInsert, buf, size);
    return size;
  case YY:
    // for (int i = 0; i < YY_MAX; i++)
    // {
    //   p = &board.yy1;
    //   p += i;
    //   size += snprintf(buf + size, 256 - size, "<td>%d</td>", *p);
    // }
    buf[size] = 0;
    strncpy(pcInsert, buf, size);
    return size;
  case YA:
    // for (int i = 0; i < YA_MAX; i++)
    // {
    //   uint16_t *pp = &board.ya1;
    //   pp += i;
    //   size += snprintf(buf + size, 256 - size, "<td>%d</td>", *pp);
    // }
    buf[size] = 0;
    strncpy(pcInsert, buf, size);
    return size;
  case XA:
    // for (int i = 0; i < XA_MAX; i++)
    // {
    //   uint16_t *pp = &board.xa1;
    //   pp += i;
    //   size += snprintf(buf + size, 256 - size, "<td>%d</td>", *pp);
    // }
    buf[size] = 0;
    strncpy(pcInsert, buf, size);
    return size;
  case XT:
    // for (int i = 0; i < XT_MAX; i++)
    // {
    //   float *pp = &board.xt1;
    //   pp += i;
    //   int val = *pp;
    //   size += snprintf(buf + size, 256 - size, "<td>%d</td>", val);
    // }
    buf[size] = 0;
    strncpy(pcInsert, buf, size);
    return size;
  case 112: //IP获取方式

    if (0) //lwipdev.dhcp_enable)
      p = (char *)"动态获取";

    else
      p = (char *)"静态";

    return WEB_dis_Handler(pcInsert, p);

    break;

  case 1112: //ip地址

    // WEB_dis_Handler(pcInsert, pIp_addr);

    break;

  case 3: //端口

    // WEB_dis_Handler(pcInsert, pIp_Localport);

    break;
  }
  return WEB_dis_Handler(pcInsert, "ERROR");
  ;
}
int FindCGIParameter(const char *pcToFind, char *pcParam[], int iNumParams)
{
  int iLoop;
  for (iLoop = 0; iLoop < iNumParams; iLoop++)
  {
    if (strcmp(pcToFind, pcParam[iLoop]) == 0)
    {
      return (iLoop); //返回iLOOP
    }
  }
  return (-1);
}

int yout_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  iIndex = FindCGIParameter("yy", pcParam, iNumParams); //找到led的索引号
  //只有一个CGI句柄 iIndex=0
  if (iIndex != -1)
  {
    int i = atoi(pcValue[iIndex]);
    // if (i < YY_MAX)
    // {
    //     char *p = &board.yy1;
    //     p += i;
    //     *p = *p?0:1; //关闭LED1灯
    // }
  }
  strcpy(uri, "/io.shtml");
  return 0;
}
int ws_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  iIndex = FindCGIParameter("url", pcParam, iNumParams); //找到led的索引号
  //只有一个CGI句柄 iIndex=0
  if (iIndex != -1)
  {
    // ws_set_url(pcValue[iIndex]);
  }
  strcpy(uri, "/ok.html");
  return 0;
}
int reboot_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  // extern uint8_t reboot;

  // reboot = 1;
  strcpy(uri, "/ok.html");
  return 0;
}
int ws_status_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{

  strcpy(uri, "/ok.html");
  return 0;
}
char txbuf[256];
int MatchMD5_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  volatile int buflen = 0;
  // if (FlashFile::stat("lastbuildPLC.md5") > 0)
  // {
  //     FlashFile md;
  //     md.open_rdonly("lastbuildPLC.md5");
  //     buflen = md.read(txbuf, 32);
  //     txbuf[buflen] = 0;
  //     // uri = txbuf;
  //     md.close();
  // }
  hs->file = txbuf;
  hs->left = buflen;
  return 2;
}
int GetPLCstatus_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  volatile int buflen = 0;
  // buflen = snprintf(txbuf, 32, "%x,0", plc_state);
  txbuf[buflen] = 0;
  // uri = txbuf;
  hs->file = txbuf;
  hs->left = buflen;
  return 2;
}
int StopPLC_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{

  // setPLCShutdown();
  strcpy(uri, "/ok.html");
  return 0;
}
int StartPLC_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  //  runPLC();
  strcpy(uri, "/ok.html");

  return 0;
}

int NewPLC_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  strcpy(uri, "/ok.html");
  return 0;
}
void format();
int format_CGIHandler(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  strcpy(uri, "/ok.html");
  format();
  return 0;
}
WEAK int hmi_get(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  return 0;
}
WEAK int hmi_set(struct http_state *hs, int iIndex, int iNumParams, char *pcParam[], char *pcValue[], char *uri, int *len)
{
  return 0;
}
static const tCGI cgis[] = //cgi程序
    {
      {"/hmi_get",hmi_get},
      {"/hmi_set",hmi_set},
        {"/yout.cgi", yout_CGIHandler},
        {"/ws.cgi", ws_CGIHandler},
        {"/reboot", reboot_CGIHandler},
        {"/ws_status", ws_status_CGIHandler},
        {"/NewPLC", NewPLC_CGIHandler},
        {"/StartPLC", StartPLC_CGIHandler},
        {"/StopPLC", StopPLC_CGIHandler},
        {"/GetPLCstatus", GetPLCstatus_CGIHandler},
        {"/format", format_CGIHandler},
        {"/MatchMD5", MatchMD5_CGIHandler}};

void httpd_cgi_handler(const char *uri, int iNumParams, char **pcParam, char **pcValue
#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
                       ,
                       void *connection_state
#endif /* LWIP_HTTPD_FILE_STATE */
)
{
}
void web_init()
{
  http_set_cgi_handlers(cgis, sizeof(cgis) / sizeof(tCGI));
  http_set_ssi_handler(SSIHandler, ppcTAGs, sizeof(ppcTAGs) / 4);
}
void httpd_setup()
{
  httpd_init();
  web_init();
}
#endif